﻿using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Xml.Schema;
using System.Collections;
using System.Globalization;
using System.ComponentModel;
using System.Xml.Serialization;
using System.Collections.Generic;

namespace XmlLinqBridge
{
   [Flags]
   public enum LoadOptions
   {
      None = 0,
      PreserveWhitespace = 1,
      SetBaseUri = 2,
      SetLineInfo = 4
   }
   [Flags]
   public enum SaveOptions
   {
      None,
      DisableFormatting
   }

   public enum XObjectChange
   {
      Add,
      Remove,
      Name,
      Value
   }

   internal class XObjectChangeAnnotation
   {
      internal EventHandler<XObjectChangeEventArgs> changed;
      internal EventHandler<XObjectChangeEventArgs> changing;
   }
   
   public class XObjectChangeEventArgs : EventArgs
   {
      public static readonly XObjectChangeEventArgs Add = new XObjectChangeEventArgs(XObjectChange.Add);
      public static readonly XObjectChangeEventArgs Name = new XObjectChangeEventArgs(XObjectChange.Name);
      private XObjectChange objectChange;
      public static readonly XObjectChangeEventArgs Remove = new XObjectChangeEventArgs(XObjectChange.Remove);
      public static readonly XObjectChangeEventArgs Value = new XObjectChangeEventArgs(XObjectChange.Value);

      public XObjectChangeEventArgs(XObjectChange objectChange)
      {
         this.objectChange = objectChange;
      }

      public XObjectChange ObjectChange
      {
         get
         {
            return this.objectChange;
         }
      }
   }

   public sealed class XNodeDocumentOrderComparer : IComparer, IComparer<XNode>
   {
      public int Compare(XNode x, XNode y)
      {
         return XNode.CompareDocumentOrder(x, y);
      }

      int IComparer.Compare(object x, object y)
      {
         XNode node = x as XNode;
         if ((node == null) && (x != null))
         {
            throw new ArgumentException("Argument_MustBeDerivedFrom", "x");
         }
         XNode node2 = y as XNode;
         if ((node2 == null) && (y != null))
         {
            throw new ArgumentException("Argument_MustBeDerivedFrom", "y");
         }
         return this.Compare(node, node2);
      }
   }

   public sealed class XNodeEqualityComparer : IEqualityComparer, IEqualityComparer<XNode>
   {
      public bool Equals(XNode x, XNode y)
      {
         return XNode.DeepEquals(x, y);
      }

      public int GetHashCode(XNode obj)
      {
         if (obj == null)
         {
            return 0;
         }
         return obj.GetDeepHashCode();
      }

      bool IEqualityComparer.Equals(object x, object y)
      {
         XNode node = x as XNode;
         if ((node == null) && (x != null))
         {
            throw new ArgumentException("Argument_MustBeDerivedFrom", "x");
         }
         XNode node2 = y as XNode;
         if ((node2 == null) && (y != null))
         {
            throw new ArgumentException("Argument_MustBeDerivedFrom", "y");
         }
         return this.Equals(node, node2);
      }

      int IEqualityComparer.GetHashCode(object obj)
      {
         XNode node = obj as XNode;
         if ((node == null) && (obj != null))
         {
            throw new ArgumentException("Argument_MustBeDerivedFrom", "obj");
         }
         return this.GetHashCode(node);
      }
   }


   public class XName
   {
   }

   public abstract class XNode : XObject
   {
      private static XNodeDocumentOrderComparer documentOrderComparer;
      private static XNodeEqualityComparer equalityComparer;
      internal XNode next;

      internal XNode()
      {
      }

      public void AddAfterSelf(object content)
      {
         if (base.parent == null)
         {
            throw new InvalidOperationException("InvalidOperation_MissingParent");
         }
         new Inserter(base.parent, this).Add(content);
      }

      public void AddAfterSelf(params object[] content)
      {
         this.AddAfterSelf(content);
      }

      public void AddBeforeSelf(object content)
      {
         if (base.parent == null)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_MissingParent"));
         }
         XNode anchor = (XNode)base.parent.content;
         while (anchor.next != this)
         {
            anchor = anchor.next;
         }
         if (anchor == base.parent.content)
         {
            anchor = null;
         }
         new Inserter(base.parent, anchor).Add(content);
      }

      public void AddBeforeSelf(params object[] content)
      {
         this.AddBeforeSelf(content);
      }

      public IEnumerable<XElement> Ancestors()
      {
         return this.GetAncestors(null, false);
      }

      public IEnumerable<XElement> Ancestors(XName name)
      {
         if (name == null)
         {
            return XElement.EmptySequence;
         }
         return this.GetAncestors(name, false);
      }

      internal virtual void AppendText(StringBuilder sb)
      {
      }

      internal abstract XNode CloneNode();
      public static int CompareDocumentOrder(XNode n1, XNode n2)
      {
         XNode next;
         if (n1 == n2)
         {
            return 0;
         }
         if (n1 == null)
         {
            return -1;
         }
         if (n2 != null)
         {
            if (n1.parent == n2.parent)
            {
               if (n1.parent == null)
               {
                  throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_MissingAncestor"));
               }
               goto Label_00CF;
            }
            int num = 0;
            XNode parent = n1;
            while (parent.parent != null)
            {
               parent = parent.parent;
               num++;
            }
            XNode node2 = n2;
            while (node2.parent != null)
            {
               node2 = node2.parent;
               num--;
            }
            if (parent != node2)
            {
               throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_MissingAncestor"));
            }
            if (num < 0)
            {
               do
               {
                  n2 = n2.parent;
                  num++;
               }
               while (num != 0);
               if (n1 == n2)
               {
                  return -1;
               }
               goto Label_00A7;
            }
            if (num <= 0)
            {
               goto Label_00A7;
            }
            do
            {
               n1 = n1.parent;
               num--;
            }
            while (num != 0);
            if (n1 != n2)
            {
               goto Label_00A7;
            }
         }
         return 1;
      Label_00A7:
         while (n1.parent != n2.parent)
         {
            n1 = n1.parent;
            n2 = n2.parent;
         }
      Label_00CF:
         next = (XNode)n1.parent.content;
         do
         {
            next = next.next;
            if (next == n1)
            {
               return -1;
            }
         }
         while (next != n2);
         return 1;
      }

      public XmlReader CreateReader()
      {
         return new XNodeReader(this, null);
      }

      internal abstract bool DeepEquals(XNode node);
      public static bool DeepEquals(XNode n1, XNode n2)
      {
         return ((n1 == n2) || (((n1 != null) && (n2 != null)) && n1.DeepEquals(n2)));
      }

      public IEnumerable<XElement> ElementsAfterSelf()
      {
         return this.GetElementsAfterSelf(null);
      }

      public IEnumerable<XElement> ElementsAfterSelf(XName name)
      {
         if (name == null)
         {
            return XElement.EmptySequence;
         }
         return this.GetElementsAfterSelf(name);
      }

      public IEnumerable<XElement> ElementsBeforeSelf()
      {
         return this.GetElementsBeforeSelf(null);
      }

      public IEnumerable<XElement> ElementsBeforeSelf(XName name)
      {
         if (name == null)
         {
            return XElement.EmptySequence;
         }
         return this.GetElementsBeforeSelf(name);
      }

      internal abstract int GetDeepHashCode();

      internal static XmlReaderSettings GetXmlReaderSettings(LoadOptions o)
      {
         XmlReaderSettings settings = new XmlReaderSettings();
         if ((o & LoadOptions.PreserveWhitespace) == LoadOptions.None)
         {
            settings.IgnoreWhitespace = true;
         }
         settings.ProhibitDtd = false;
         settings.MaxCharactersFromEntities = 0x989680L;
         settings.XmlResolver = null;
         return settings;
      }

      private string GetXmlString(SaveOptions o)
      {
         using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture))
         {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true;
            if ((o & SaveOptions.DisableFormatting) == SaveOptions.None)
            {
               settings.Indent = true;
            }
            if (this is XText)
            {
               settings.ConformanceLevel = ConformanceLevel.Fragment;
            }
            using (XmlWriter writer2 = XmlWriter.Create(writer, settings))
            {
               XDocument document = this as XDocument;
               if (document != null)
               {
                  document.WriteContentTo(writer2);
               }
               else
               {
                  this.WriteTo(writer2);
               }
            }
            return writer.ToString();
         }
      }

      internal static XmlWriterSettings GetXmlWriterSettings(SaveOptions o)
      {
         XmlWriterSettings settings = new XmlWriterSettings();
         if ((o & SaveOptions.DisableFormatting) == SaveOptions.None)
         {
            settings.Indent = true;
         }
         return settings;
      }

      public bool IsAfter(XNode node)
      {
         return (CompareDocumentOrder(this, node) > 0);
      }

      public bool IsBefore(XNode node)
      {
         return (CompareDocumentOrder(this, node) < 0);
      }

      public static XNode ReadFrom(XmlReader reader)
      {
         if (reader == null)
         {
            throw new ArgumentNullException("reader");
         }
         if (reader.ReadState != ReadState.Interactive)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExpectedInteractive"));
         }
         switch (reader.NodeType)
         {
            case XmlNodeType.Element:
            return new XElement(reader);

            case XmlNodeType.Text:
            case XmlNodeType.Whitespace:
            case XmlNodeType.SignificantWhitespace:
            return new XText(reader);

            case XmlNodeType.CDATA:
            return new XCData(reader);

            case XmlNodeType.ProcessingInstruction:
            return new XProcessingInstruction(reader);

            case XmlNodeType.Comment:
            return new XComment(reader);

            case XmlNodeType.DocumentType:
            return new XDocumentType(reader);
         }
         throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_UnexpectedNodeType", new object[] { reader.NodeType }));
      }

      public void Remove()
      {
         if (base.parent == null)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_MissingParent"));
         }
         base.parent.RemoveNode(this);
      }

      public void ReplaceWith(object content)
      {
         if (base.parent == null)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_MissingParent"));
         }
         XContainer parent = base.parent;
         XNode anchor = (XNode)base.parent.content;
         while (anchor.next != this)
         {
            anchor = anchor.next;
         }
         if (anchor == base.parent.content)
         {
            anchor = null;
         }
         base.parent.RemoveNode(this);
         if ((anchor != null) && (anchor.parent != parent))
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExternalCode"));
         }
         new Inserter(parent, anchor).Add(content);
      }

      public void ReplaceWith(params object[] content)
      {
         this.ReplaceWith(content);
      }

      public override string ToString()
      {
         return this.GetXmlString(SaveOptions.None);
      }

      public string ToString(SaveOptions options)
      {
         return this.GetXmlString(options);
      }

      public abstract void WriteTo(XmlWriter writer);

      public static XNodeDocumentOrderComparer DocumentOrderComparer
      {
         get
         {
            if (documentOrderComparer == null)
            {
               documentOrderComparer = new XNodeDocumentOrderComparer();
            }
            return documentOrderComparer;
         }
      }

      public static XNodeEqualityComparer EqualityComparer
      {
         get
         {
            if (equalityComparer == null)
            {
               equalityComparer = new XNodeEqualityComparer();
            }
            return equalityComparer;
         }
      }

      public XNode NextNode
      {
         get
         {
            if ((base.parent != null) && (this != base.parent.content))
            {
               return this.next;
            }
            return null;
         }
      }

      public XNode PreviousNode
      {
         get
         {
            if (base.parent == null)
            {
               return null;
            }
            XNode next = ((XNode)base.parent.content).next;
            XNode node2 = null;
            while (next != this)
            {
               node2 = next;
               next = next.next;
            }
            return node2;
         }
      }
   }

   public abstract class XObject : IXmlLineInfo
   {
      internal object annotations;
      internal XContainer parent;

      public event EventHandler<XObjectChangeEventArgs> Changed
      {
         add
         {
            if (value != null)
            {
               XObjectChangeAnnotation annotation = this.Annotation<XObjectChangeAnnotation>();
               if (annotation == null)
               {
                  annotation = new XObjectChangeAnnotation();
                  this.AddAnnotation(annotation);
               }
               annotation.changed = (EventHandler<XObjectChangeEventArgs>)Delegate.Combine(annotation.changed, value);
            }
         }
         remove
         {
            if (value != null)
            {
               XObjectChangeAnnotation annotation = this.Annotation<XObjectChangeAnnotation>();
               if (annotation != null)
               {
                  annotation.changed = (EventHandler<XObjectChangeEventArgs>)Delegate.Remove(annotation.changed, value);
                  if ((annotation.changing == null) && (annotation.changed == null))
                  {
                     this.RemoveAnnotations<XObjectChangeAnnotation>();
                  }
               }
            }
         }
      }

      public event EventHandler<XObjectChangeEventArgs> Changing
      {
         add
         {
            if (value != null)
            {
               XObjectChangeAnnotation annotation = this.Annotation<XObjectChangeAnnotation>();
               if (annotation == null)
               {
                  annotation = new XObjectChangeAnnotation();
                  this.AddAnnotation(annotation);
               }
               annotation.changing = (EventHandler<XObjectChangeEventArgs>)Delegate.Combine(annotation.changing, value);
            }
         }
         remove
         {
            if (value != null)
            {
               XObjectChangeAnnotation annotation = this.Annotation<XObjectChangeAnnotation>();
               if (annotation != null)
               {
                  annotation.changing = (EventHandler<XObjectChangeEventArgs>)Delegate.Remove(annotation.changing, value);
                  if ((annotation.changing == null) && (annotation.changed == null))
                  {
                     this.RemoveAnnotations<XObjectChangeAnnotation>();
                  }
               }
            }
         }
      }

      internal XObject()
      {
      }

      public void AddAnnotation(object annotation)
      {
         if (annotation == null)
         {
            throw new ArgumentNullException("annotation");
         }
         if (this.annotations == null)
         {
            this.annotations = (annotation is object[]) ? new object[] { annotation } : annotation;
         }
         else
         {
            object[] annotations = this.annotations as object[];
            if (annotations == null)
            {
               this.annotations = new object[] { this.annotations, annotation };
            }
            else
            {
               int index = 0;
               while ((index < annotations.Length) && (annotations[index] != null))
               {
                  index++;
               }
               if (index == annotations.Length)
               {
                  Array.Resize<object>(ref annotations, index * 2);
                  this.annotations = annotations;
               }
               annotations[index] = annotation;
            }
         }
      }

      public T Annotation<T>() where T : class
      {
         if (this.annotations != null)
         {
            object[] annotations = this.annotations as object[];
            if (annotations == null)
            {
               return (this.annotations as T);
            }
            for (int i = 0; i < annotations.Length; i++)
            {
               object obj2 = annotations[i];
               if (obj2 == null)
               {
                  break;
               }
               T local = obj2 as T;
               if (local != null)
               {
                  return local;
               }
            }
         }
         return default(T);
      }

      public object Annotation(Type type)
      {
         if (type == null)
         {
            throw new ArgumentNullException("type");
         }
         if (this.annotations != null)
         {
            object[] annotations = this.annotations as object[];
            if (annotations == null)
            {
               if (type.IsInstanceOfType(this.annotations))
               {
                  return this.annotations;
               }
            }
            else
            {
               for (int i = 0; i < annotations.Length; i++)
               {
                  object o = annotations[i];
                  if (o == null)
                  {
                     break;
                  }
                  if (type.IsInstanceOfType(o))
                  {
                     return o;
                  }
               }
            }
         }
         return null;
      }

      internal bool NotifyChanged(object sender, XObjectChangeEventArgs e)
      {
         bool flag = false;
         XObject parent = this;
         while (true)
         {
            while ((parent != null) && (parent.annotations == null))
            {
               parent = parent.parent;
            }
            if (parent == null)
            {
               return flag;
            }
            XObjectChangeAnnotation annotation = parent.Annotation<XObjectChangeAnnotation>();
            if (annotation != null)
            {
               flag = true;
               if (annotation.changed != null)
               {
                  annotation.changed(sender, e);
               }
            }
            parent = parent.parent;
         }
      }

      internal bool NotifyChanging(object sender, XObjectChangeEventArgs e)
      {
         bool flag = false;
         XObject parent = this;
         while (true)
         {
            while ((parent != null) && (parent.annotations == null))
            {
               parent = parent.parent;
            }
            if (parent == null)
            {
               return flag;
            }
            XObjectChangeAnnotation annotation = parent.Annotation<XObjectChangeAnnotation>();
            if (annotation != null)
            {
               flag = true;
               if (annotation.changing != null)
               {
                  annotation.changing(sender, e);
               }
            }
            parent = parent.parent;
         }
      }

      public void RemoveAnnotations<T>() where T : class
      {
         if (this.annotations != null)
         {
            object[] annotations = this.annotations as object[];
            if (annotations == null)
            {
               if (this.annotations is T)
               {
                  this.annotations = null;
               }
            }
            else
            {
               int index = 0;
               int num2 = 0;
               while (index < annotations.Length)
               {
                  object obj2 = annotations[index];
                  if (obj2 == null)
                  {
                     break;
                  }
                  if (!(obj2 is T))
                  {
                     annotations[num2++] = obj2;
                  }
                  index++;
               }
               if (num2 != 0)
               {
                  while (num2 < index)
                  {
                     annotations[num2++] = null;
                  }
               }
               else
               {
                  this.annotations = null;
               }
            }
         }
      }

      public void RemoveAnnotations(Type type)
      {
         if (type == null)
         {
            throw new ArgumentNullException("type");
         }
         if (this.annotations != null)
         {
            object[] annotations = this.annotations as object[];
            if (annotations == null)
            {
               if (type.IsInstanceOfType(this.annotations))
               {
                  this.annotations = null;
               }
            }
            else
            {
               int index = 0;
               int num2 = 0;
               while (index < annotations.Length)
               {
                  object o = annotations[index];
                  if (o == null)
                  {
                     break;
                  }
                  if (!type.IsInstanceOfType(o))
                  {
                     annotations[num2++] = o;
                  }
                  index++;
               }
               if (num2 != 0)
               {
                  while (num2 < index)
                  {
                     annotations[num2++] = null;
                  }
               }
               else
               {
                  this.annotations = null;
               }
            }
         }
      }

      bool IXmlLineInfo.HasLineInfo()
      {
         return false;
      }

      public string BaseUri
      {
         get
         {
            XObject parent = this;
            while (true)
            {
               while ((parent != null) && (parent.annotations == null))
               {
                  parent = parent.parent;
               }
               if (parent == null)
               {
                  return string.Empty;
               }
               parent = parent.parent;
            }
         }
      }

      internal bool HasBaseUri
      {
         get
         {
            return false;
         }
      }

      public abstract XmlNodeType NodeType { get; }

      public XElement Parent
      {
         get
         {
            return (this.parent as XElement);
         }
      }

      int IXmlLineInfo.LineNumber
      {
         get
         {
            return 0;
         }
      }

      int IXmlLineInfo.LinePosition
      {
         get
         {
            return 0;
         }
      }
   }

   public class XNamespace
   {
      public string NamespaceName
      {
         get
         {
            throw new NotImplementedException();
         }
      }
   }

   public abstract class XContainer : XNode
   {
      internal object content;

      internal XContainer()
      {
      }

      internal XContainer(XContainer other)
      {
         if (other == null)
         {
            throw new ArgumentNullException("other");
         }
         if (other.content is string)
         {
            this.content = other.content;
         }
         else
         {
            XNode content = (XNode)other.content;
            if (content != null)
            {
               do
               {
                  this.AppendNodeSkipNotify(content.next.CloneNode());
               }
               while (content != other.content);
            }
         }
      }

      public void Add(object content)
      {
         if (base.SkipNotify())
         {
            this.AddContentSkipNotify(content);
         }
         else if (content != null)
         {
            XNode n = content as XNode;
            if (n != null)
            {
               this.AddNode(n);
            }
            else
            {
               string s = content as string;
               if (s != null)
               {
                  this.AddString(s);
               }
               else
               {
                  XAttribute a = content as XAttribute;
                  if (a != null)
                  {
                     this.AddAttribute(a);
                  }
                  else
                  {
                     XStreamingElement other = content as XStreamingElement;
                     if (other != null)
                     {
                        this.AddNode(new XElement(other));
                     }
                     else
                     {
                        object[] objArray = content as object[];
                        if (objArray != null)
                        {
                           foreach (object obj2 in objArray)
                           {
                              this.Add(obj2);
                           }
                        }
                        else
                        {
                           IEnumerable enumerable = content as IEnumerable;
                           if (enumerable != null)
                           {
                              foreach (object obj3 in enumerable)
                              {
                                 this.Add(obj3);
                              }
                           }
                           else
                           {
                              this.AddString(GetStringValue(content));
                           }
                        }
                     }
                  }
               }
            }
         }
      }

      public void Add(params object[] content)
      {
         this.Add(content);
      }

      internal virtual void AddAttribute(XAttribute a)
      {
      }

      internal virtual void AddAttributeSkipNotify(XAttribute a)
      {
      }

      internal void AddContentSkipNotify(object content)
      {
         if (content != null)
         {
            XNode n = content as XNode;
            if (n != null)
            {
               this.AddNodeSkipNotify(n);
            }
            else
            {
               string s = content as string;
               if (s != null)
               {
                  this.AddStringSkipNotify(s);
               }
               else
               {
                  XAttribute a = content as XAttribute;
                  if (a != null)
                  {
                     this.AddAttributeSkipNotify(a);
                  }
                  else
                  {
                     XStreamingElement other = content as XStreamingElement;
                     if (other != null)
                     {
                        this.AddNodeSkipNotify(new XElement(other));
                     }
                     else
                     {
                        object[] objArray = content as object[];
                        if (objArray != null)
                        {
                           foreach (object obj2 in objArray)
                           {
                              this.AddContentSkipNotify(obj2);
                           }
                        }
                        else
                        {
                           IEnumerable enumerable = content as IEnumerable;
                           if (enumerable != null)
                           {
                              foreach (object obj3 in enumerable)
                              {
                                 this.AddContentSkipNotify(obj3);
                              }
                           }
                           else
                           {
                              this.AddStringSkipNotify(GetStringValue(content));
                           }
                        }
                     }
                  }
               }
            }
         }
      }

      private static void AddContentToList(List<object> list, object content)
      {
         IEnumerable enumerable = (content is string) ? null : (content as IEnumerable);
         if (enumerable == null)
         {
            list.Add(content);
         }
         else
         {
            foreach (object obj2 in enumerable)
            {
               if (obj2 != null)
               {
                  AddContentToList(list, obj2);
               }
            }
         }
      }

      public void AddFirst(object content)
      {
         new Inserter(this, null).Add(content);
      }

      public void AddFirst(params object[] content)
      {
         this.AddFirst(content);
      }

      internal void AddNode(XNode n)
      {
         this.ValidateNode(n, this);
         if (n.parent != null)
         {
            n = n.CloneNode();
         }
         else
         {
            XNode parent = this;
            while (parent.parent != null)
            {
               parent = parent.parent;
            }
            if (n == parent)
            {
               n = n.CloneNode();
            }
         }
         this.ConvertTextToNode();
         this.AppendNode(n);
      }

      internal void AddNodeSkipNotify(XNode n)
      {
         this.ValidateNode(n, this);
         if (n.parent != null)
         {
            n = n.CloneNode();
         }
         else
         {
            XNode parent = this;
            while (parent.parent != null)
            {
               parent = parent.parent;
            }
            if (n == parent)
            {
               n = n.CloneNode();
            }
         }
         this.ConvertTextToNode();
         this.AppendNodeSkipNotify(n);
      }

      internal void AddString(string s)
      {
         this.ValidateString(s);
         if (this.content == null)
         {
            if (s.Length > 0)
            {
               this.AppendNode(new XText(s));
            }
            else if (this is XElement)
            {
               base.NotifyChanging(this, XObjectChangeEventArgs.Value);
               if (this.content != null)
               {
                  throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExternalCode"));
               }
               this.content = s;
               base.NotifyChanged(this, XObjectChangeEventArgs.Value);
            }
            else
            {
               this.content = s;
            }
         }
         else if (s.Length > 0)
         {
            this.ConvertTextToNode();
            XText content = this.content as XText;
            if ((content != null) && !(content is XCData))
            {
               content.Value = content.Value + s;
            }
            else
            {
               this.AppendNode(new XText(s));
            }
         }
      }

      internal void AddStringSkipNotify(string s)
      {
         this.ValidateString(s);
         if (this.content == null)
         {
            this.content = s;
         }
         else if (s.Length > 0)
         {
            if (this.content is string)
            {
               this.content = ((string)this.content) + s;
            }
            else
            {
               XText content = this.content as XText;
               if ((content != null) && !(content is XCData))
               {
                  content.text = content.text + s;
               }
               else
               {
                  this.AppendNodeSkipNotify(new XText(s));
               }
            }
         }
      }

      internal void AppendNode(XNode n)
      {
         bool flag = base.NotifyChanging(n, XObjectChangeEventArgs.Add);
         if (n.parent != null)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExternalCode"));
         }
         this.AppendNodeSkipNotify(n);
         if (flag)
         {
            base.NotifyChanged(n, XObjectChangeEventArgs.Add);
         }
      }

      internal void AppendNodeSkipNotify(XNode n)
      {
         n.parent = this;
         if ((this.content == null) || (this.content is string))
         {
            n.next = n;
         }
         else
         {
            XNode content = (XNode)this.content;
            n.next = content.next;
            content.next = n;
         }
         this.content = n;
      }

      internal override void AppendText(StringBuilder sb)
      {
         string content = this.content as string;
         if (content != null)
         {
            sb.Append(content);
         }
         else
         {
            XNode node = (XNode)this.content;
            if (node != null)
            {
               do
               {
                  node.next.AppendText(sb);
               }
               while (node != this.content);
            }
         }
      }

      private string CollectText(ref XNode n)
      {
         string str = "";
         while ((n != null) && (n.NodeType == XmlNodeType.Text))
         {
            str = str + ((XText)n).Value;
            n = (n != this.content) ? n.next : null;
         }
         return str;
      }

      internal bool ContentsEqual(XContainer e)
      {
         if (this.content == e.content)
         {
            return true;
         }
         string textOnly = this.GetTextOnly();
         if (textOnly != null)
         {
            return (textOnly == e.GetTextOnly());
         }
         XNode content = this.content as XNode;
         XNode n = e.content as XNode;
         if ((content == null) || (n == null))
         {
            goto Label_00A9;
         }
         content = content.next;
         n = n.next;
      Label_0053:
         if (this.CollectText(ref content) == e.CollectText(ref n))
         {
            if ((content == null) && (n == null))
            {
               return true;
            }
            if (((content != null) && (n != null)) && content.DeepEquals(n))
            {
               content = (content != this.content) ? content.next : null;
               n = (n != e.content) ? n.next : null;
               goto Label_0053;
            }
         }
      Label_00A9:
         return false;
      }

      internal int ContentsHashCode()
      {
         string textOnly = this.GetTextOnly();
         if (textOnly != null)
         {
            return textOnly.GetHashCode();
         }
         int num = 0;
         XNode content = this.content as XNode;
         if (content == null)
         {
            return num;
         }
      Label_0022:
         content = content.next;
         string str2 = this.CollectText(ref content);
         if (str2.Length > 0)
         {
            num ^= str2.GetHashCode();
         }
         if (content != null)
         {
            num ^= content.GetDeepHashCode();
            if (content != this.content)
            {
               goto Label_0022;
            }
         }
         return num;
      }

      internal void ConvertTextToNode()
      {
         string content = this.content as string;
         if ((content != null) && (content.Length > 0))
         {
            XText text = new XText(content);
            text.parent = this;
            text.next = text;
            this.content = text;
         }
      }

      public XmlWriter CreateWriter()
      {
         XmlWriterSettings settings = new XmlWriterSettings();
         settings.ConformanceLevel = (this is XDocument) ? ConformanceLevel.Document : ConformanceLevel.Fragment;
         return XmlWriter.Create(new XNodeBuilder(this), settings);
      }

      public IEnumerable<XNode> DescendantNodes()
      {
         return this.GetDescendantNodes(false);
      }

      public IEnumerable<XElement> Descendants()
      {
         return this.GetDescendants(null, false);
      }

      public IEnumerable<XElement> Descendants(XName name)
      {
         if (name == null)
         {
            return XElement.EmptySequence;
         }
         return this.GetDescendants(name, false);
      }

      public XElement Element(XName name)
      {
         XNode content = this.content as XNode;
         if (content != null)
         {
            do
            {
               content = content.next;
               XElement element = content as XElement;
               if ((element != null) && (element.name == name))
               {
                  return element;
               }
            }
            while (content != this.content);
         }
         return null;
      }

      public IEnumerable<XElement> Elements()
      {
         return this.GetElements(null);
      }

      public IEnumerable<XElement> Elements(XName name)
      {
         if (name == null)
         {
            return XElement.EmptySequence;
         }
         return this.GetElements(name);
      }

      internal static object GetContentSnapshot(object content)
      {
         if ((content is string) || !(content is IEnumerable))
         {
            return content;
         }
         List<object> list = new List<object>();
         AddContentToList(list, content);
         return list;
      }

      internal static string GetDateTimeString(DateTime value)
      {
         return XmlConvert.ToString(value, XmlDateTimeSerializationMode.RoundtripKind);
      }
      //!
      internal IEnumerable<XNode> GetDescendantNodes(bool self)
      {
         //<GetDescendantNodes>d__4 d__ = new <GetDescendantNodes>d__4(-2);
         //d__.<>4__this = this;
         //d__.<>3__self = self;
         //return d__;
         return null;
      }
      //!
      internal IEnumerable<XElement> GetDescendants(XName name, bool self)
      {
         //<GetDescendants>d__a _a = new <GetDescendants>d__a(-2);
         //_a.<>4__this = this;
         //_a.<>3__name = name;
         //_a.<>3__self = self;
         //return _a;
         return null;
      }
      //!
      private IEnumerable<XElement> GetElements(XName name)
      {
         //<GetElements>d__11 d__ = new <GetElements>d__11(-2);
         //d__.<>4__this = this;
         //d__.<>3__name = name;
         //return d__;
         return null;
      }

      internal static string GetStringValue(object value)
      {
         string dateTimeString;
         if (value is string)
         {
            dateTimeString = (string)value;
         }
         else if (value is double)
         {
            dateTimeString = XmlConvert.ToString((double)value);
         }
         else if (value is float)
         {
            dateTimeString = XmlConvert.ToString((float)value);
         }
         else if (value is decimal)
         {
            dateTimeString = XmlConvert.ToString((decimal)value);
         }
         else if (value is bool)
         {
            dateTimeString = XmlConvert.ToString((bool)value);
         }
         else if (value is DateTime)
         {
            dateTimeString = GetDateTimeString((DateTime)value);
         }
         else if (value is DateTimeOffset)
         {
            dateTimeString = XmlConvert.ToString((DateTimeOffset)value);
         }
         else if (value is TimeSpan)
         {
            dateTimeString = XmlConvert.ToString((TimeSpan)value);
         }
         else
         {
            if (value is XObject)
            {
               throw new ArgumentException(System.Xml.Linq.Res.GetString("Argument_XObjectValue"));
            }
            dateTimeString = value.ToString();
         }
         if (dateTimeString == null)
         {
            throw new ArgumentException(System.Xml.Linq.Res.GetString("Argument_ConvertToString"));
         }
         return dateTimeString;
      }

      private string GetTextOnly()
      {
         if (this.content == null)
         {
            return null;
         }
         string content = this.content as string;
         if (content == null)
         {
            XNode next = (XNode)this.content;
            do
            {
               next = next.next;
               if (next.NodeType != XmlNodeType.Text)
               {
                  return null;
               }
               content = content + ((XText)next).Value;
            }
            while (next != this.content);
         }
         return content;
      }

      //!
      public IEnumerable<XNode> Nodes()
      {
         //<Nodes>d__0 d__ = new <Nodes>d__0(-2);
         //d__.<>4__this = this;
         //return d__;
         return null;
      }

      internal void ReadContentFrom(XmlReader r)
      {
         if (r.ReadState != ReadState.Interactive)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExpectedInteractive"));
         }
         XContainer parent = this;
         NamespaceCache cache = new NamespaceCache();
         NamespaceCache cache2 = new NamespaceCache();
         do
         {
            switch (r.NodeType)
            {
               case XmlNodeType.Element:
               {
                  XElement n = new XElement(cache.Get(r.NamespaceURI).GetName(r.LocalName));
                  if (r.MoveToFirstAttribute())
                  {
                     do
                     {
                        n.AppendAttributeSkipNotify(new XAttribute(cache2.Get((r.Prefix.Length == 0) ? string.Empty : r.NamespaceURI).GetName(r.LocalName), r.Value));
                     }
                     while (r.MoveToNextAttribute());
                     r.MoveToElement();
                  }
                  parent.AddNodeSkipNotify(n);
                  if (!r.IsEmptyElement)
                  {
                     parent = n;
                  }
                  break;
               }
               case XmlNodeType.Text:
               case XmlNodeType.Whitespace:
               case XmlNodeType.SignificantWhitespace:
               parent.AddStringSkipNotify(r.Value);
               break;

               case XmlNodeType.CDATA:
               parent.AddNodeSkipNotify(new XCData(r.Value));
               break;

               case XmlNodeType.EntityReference:
               if (!r.CanResolveEntity)
               {
                  throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_UnresolvedEntityReference"));
               }
               r.ResolveEntity();
               break;

               case XmlNodeType.ProcessingInstruction:
               parent.AddNodeSkipNotify(new XProcessingInstruction(r.Name, r.Value));
               break;

               case XmlNodeType.Comment:
               parent.AddNodeSkipNotify(new XComment(r.Value));
               break;

               case XmlNodeType.DocumentType:
               parent.AddNodeSkipNotify(new XDocumentType(r.LocalName, r.GetAttribute("PUBLIC"), r.GetAttribute("SYSTEM"), r.Value));
               break;

               case XmlNodeType.EndElement:
               if (parent.content == null)
               {
                  parent.content = string.Empty;
               }
               if (parent == this)
               {
                  return;
               }
               parent = parent.parent;
               break;

               case XmlNodeType.EndEntity:
               break;

               default:
               throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_UnexpectedNodeType", new object[] { r.NodeType }));
            }
         }
         while (r.Read());
      }

      internal void ReadContentFrom(XmlReader r, LoadOptions o)
      {
         if ((o & (LoadOptions.SetLineInfo | LoadOptions.SetBaseUri)) == LoadOptions.None)
         {
            this.ReadContentFrom(r);
         }
         else
         {
            if (r.ReadState != ReadState.Interactive)
            {
               throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExpectedInteractive"));
            }
            XContainer parent = this;
            XNode n = null;
            NamespaceCache cache = new NamespaceCache();
            NamespaceCache cache2 = new NamespaceCache();
            string baseUri = ((o & LoadOptions.SetBaseUri) != LoadOptions.None) ? r.BaseURI : null;
            IXmlLineInfo info = ((o & LoadOptions.SetLineInfo) != LoadOptions.None) ? (r as IXmlLineInfo) : null;
            do
            {
               string baseURI = r.BaseURI;
               switch (r.NodeType)
               {
                  case XmlNodeType.Element:
                  {
                     XElement element = new XElement(cache.Get(r.NamespaceURI).GetName(r.LocalName));
                     if ((baseUri != null) && (baseUri != baseURI))
                     {
                        element.SetBaseUri(baseURI);
                     }
                     if ((info != null) && info.HasLineInfo())
                     {
                        element.SetLineInfo(info.LineNumber, info.LinePosition);
                     }
                     if (r.MoveToFirstAttribute())
                     {
                        do
                        {
                           XAttribute a = new XAttribute(cache2.Get((r.Prefix.Length == 0) ? string.Empty : r.NamespaceURI).GetName(r.LocalName), r.Value);
                           if ((info != null) && info.HasLineInfo())
                           {
                              a.SetLineInfo(info.LineNumber, info.LinePosition);
                           }
                           element.AppendAttributeSkipNotify(a);
                        }
                        while (r.MoveToNextAttribute());
                        r.MoveToElement();
                     }
                     parent.AddNodeSkipNotify(element);
                     if (!r.IsEmptyElement)
                     {
                        parent = element;
                        if (baseUri != null)
                        {
                           baseUri = baseURI;
                        }
                     }
                     break;
                  }
                  case XmlNodeType.Text:
                  case XmlNodeType.Whitespace:
                  case XmlNodeType.SignificantWhitespace:
                  if (((baseUri == null) || (baseUri == baseURI)) && ((info == null) || !info.HasLineInfo()))
                  {
                     parent.AddStringSkipNotify(r.Value);
                  }
                  else
                  {
                     n = new XText(r.Value);
                  }
                  break;

                  case XmlNodeType.CDATA:
                  n = new XCData(r.Value);
                  break;

                  case XmlNodeType.EntityReference:
                  if (!r.CanResolveEntity)
                  {
                     throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_UnresolvedEntityReference"));
                  }
                  r.ResolveEntity();
                  break;

                  case XmlNodeType.ProcessingInstruction:
                  n = new XProcessingInstruction(r.Name, r.Value);
                  break;

                  case XmlNodeType.Comment:
                  n = new XComment(r.Value);
                  break;

                  case XmlNodeType.DocumentType:
                  n = new XDocumentType(r.LocalName, r.GetAttribute("PUBLIC"), r.GetAttribute("SYSTEM"), r.Value);
                  break;

                  case XmlNodeType.EndElement:
                  if (parent.content == null)
                  {
                     parent.content = string.Empty;
                  }
                  if (parent == this)
                  {
                     return;
                  }
                  if ((baseUri != null) && parent.HasBaseUri)
                  {
                     baseUri = parent.parent.BaseUri;
                  }
                  parent = parent.parent;
                  break;

                  case XmlNodeType.EndEntity:
                  break;

                  default:
                  throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_UnexpectedNodeType", new object[] { r.NodeType }));
               }
               if (n != null)
               {
                  if ((baseUri != null) && (baseUri != baseURI))
                  {
                     n.SetBaseUri(baseURI);
                  }
                  if ((info != null) && info.HasLineInfo())
                  {
                     n.SetLineInfo(info.LineNumber, info.LinePosition);
                  }
                  parent.AddNodeSkipNotify(n);
                  n = null;
               }
            }
            while (r.Read());
         }
      }

      internal void RemoveNode(XNode n)
      {
         bool flag = base.NotifyChanging(n, XObjectChangeEventArgs.Remove);
         if (n.parent != this)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExternalCode"));
         }
         XNode content = (XNode)this.content;
         while (content.next != n)
         {
            content = content.next;
         }
         if (content == n)
         {
            this.content = null;
         }
         else
         {
            if (this.content == n)
            {
               this.content = content;
            }
            content.next = n.next;
         }
         n.parent = null;
         n.next = null;
         if (flag)
         {
            base.NotifyChanged(n, XObjectChangeEventArgs.Remove);
         }
      }

      public void RemoveNodes()
      {
         if (base.SkipNotify())
         {
            this.RemoveNodesSkipNotify();
         }
         else
         {
            while (this.content != null)
            {
               string content = this.content as string;
               if (content != null)
               {
                  if (content.Length > 0)
                  {
                     this.ConvertTextToNode();
                  }
                  else if (this is XElement)
                  {
                     base.NotifyChanging(this, XObjectChangeEventArgs.Value);
                     if (content != this.content)
                     {
                        throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExternalCode"));
                     }
                     this.content = null;
                     base.NotifyChanged(this, XObjectChangeEventArgs.Value);
                  }
                  else
                  {
                     this.content = null;
                  }
               }
               XNode node = this.content as XNode;
               if (node != null)
               {
                  XNode next = node.next;
                  base.NotifyChanging(next, XObjectChangeEventArgs.Remove);
                  if ((node != this.content) || (next != node.next))
                  {
                     throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExternalCode"));
                  }
                  if (next != node)
                  {
                     node.next = next.next;
                  }
                  else
                  {
                     this.content = null;
                  }
                  next.parent = null;
                  next.next = null;
                  base.NotifyChanged(next, XObjectChangeEventArgs.Remove);
               }
            }
         }
      }

      private void RemoveNodesSkipNotify()
      {
         XNode content = this.content as XNode;
         if (content != null)
         {
            do
            {
               XNode next = content.next;
               content.parent = null;
               content.next = null;
               content = next;
            }
            while (content != this.content);
         }
         this.content = null;
      }

      public void ReplaceNodes(object content)
      {
         content = GetContentSnapshot(content);
         this.RemoveNodes();
         this.Add(content);
      }

      public void ReplaceNodes(params object[] content)
      {
         this.ReplaceNodes(content);
      }

      internal virtual void ValidateNode(XNode node, XNode previous)
      {
      }

      internal virtual void ValidateString(string s)
      {
      }

      internal void WriteContentTo(XmlWriter writer)
      {
         if (this.content != null)
         {
            if (this.content is string)
            {
               if (this is XDocument)
               {
                  writer.WriteWhitespace((string)this.content);
               }
               else
               {
                  writer.WriteString((string)this.content);
               }
            }
            else
            {
               XNode content = (XNode)this.content;
               do
               {
                  content.next.WriteTo(writer);
               }
               while (content != this.content);
            }
         }
      }

      public XNode FirstNode
      {
         get
         {
            XNode lastNode = this.LastNode;
            if (lastNode == null)
            {
               return null;
            }
            return lastNode.next;
         }
      }

      public XNode LastNode
      {
         get
         {
            if (this.content == null)
            {
               return null;
            }
            XNode content = this.content as XNode;
            if (content != null)
            {
               return content;
            }
            string str = this.content as string;
            if (str != null)
            {
               if (str.Length == 0)
               {
                  return null;
               }
               XText text = new XText(str);
               text.parent = this;
               text.next = text;
               Interlocked.CompareExchange(ref this.content, text, str);
            }
            return (XNode)this.content;
         }
      }
   }

   public class XElement : XContainer, IXmlSerializable
   {
      private static IEnumerable<XElement> emptySequence;
      internal XAttribute lastAttr;
      internal XName name;

      internal XElement()
         : this("default")
      {
      }

      public XElement(XElement other)
         : base(other)
      {
         this.name = other.name;
         XAttribute lastAttr = other.lastAttr;
         if (lastAttr != null)
         {
            do
            {
               lastAttr = lastAttr.next;
               this.AppendAttributeSkipNotify(new XAttribute(lastAttr));
            }
            while (lastAttr != other.lastAttr);
         }
      }

      public XElement(XName name)
      {
         if (name == null)
         {
            throw new ArgumentNullException("name");
         }
         this.name = name;
      }

      internal XElement(XmlReader r)
         : this(r, LoadOptions.None)
      {
      }

      public XElement(XName name, object content)
         : this(name)
      {
         base.AddContentSkipNotify(content);
      }

      public XElement(XName name, params object[] content)
         : this(name, content)
      {
      }

      internal XElement(XmlReader r, LoadOptions o)
      {
         this.ReadElementFrom(r, o);
      }

      internal override void AddAttribute(XAttribute a)
      {
         if (this.Attribute(a.Name) != null)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_DuplicateAttribute"));
         }
         if (a.parent != null)
         {
            a = new XAttribute(a);
         }
         this.AppendAttribute(a);
      }

      internal override void AddAttributeSkipNotify(XAttribute a)
      {
         if (this.Attribute(a.Name) != null)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_DuplicateAttribute"));
         }
         if (a.parent != null)
         {
            a = new XAttribute(a);
         }
         this.AppendAttributeSkipNotify(a);
      }

      public IEnumerable<XElement> AncestorsAndSelf()
      {
         return base.GetAncestors(null, true);
      }

      public IEnumerable<XElement> AncestorsAndSelf(XName name)
      {
         if (name == null)
         {
            return EmptySequence;
         }
         return base.GetAncestors(name, true);
      }

      internal void AppendAttribute(XAttribute a)
      {
         bool flag = base.NotifyChanging(a, XObjectChangeEventArgs.Add);
         if (a.parent != null)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExternalCode"));
         }
         this.AppendAttributeSkipNotify(a);
         if (flag)
         {
            base.NotifyChanged(a, XObjectChangeEventArgs.Add);
         }
      }

      internal void AppendAttributeSkipNotify(XAttribute a)
      {
         a.parent = this;
         if (this.lastAttr == null)
         {
            a.next = a;
         }
         else
         {
            a.next = this.lastAttr.next;
            this.lastAttr.next = a;
         }
         this.lastAttr = a;
      }

      public XAttribute Attribute(XName name)
      {
         XAttribute lastAttr = this.lastAttr;
         if (lastAttr != null)
         {
            do
            {
               lastAttr = lastAttr.next;
               if (lastAttr.name == name)
               {
                  return lastAttr;
               }
            }
            while (lastAttr != this.lastAttr);
         }
         return null;
      }

      public IEnumerable<XAttribute> Attributes()
      {
         return this.GetAttributes(null);
      }

      public IEnumerable<XAttribute> Attributes(XName name)
      {
         if (name == null)
         {
            return XAttribute.EmptySequence;
         }
         return this.GetAttributes(name);
      }

      private bool AttributesEqual(XElement e)
      {
         XAttribute lastAttr = this.lastAttr;
         XAttribute next = e.lastAttr;
         if ((lastAttr != null) && (next != null))
         {
            do
            {
               lastAttr = lastAttr.next;
               next = next.next;
               if ((lastAttr.name != next.name) || (lastAttr.value != next.value))
               {
                  return false;
               }
            }
            while (lastAttr != this.lastAttr);
            return (next == e.lastAttr);
         }
         return ((lastAttr == null) && (next == null));
      }

      internal override XNode CloneNode()
      {
         return new XElement(this);
      }

      internal override bool DeepEquals(XNode node)
      {
         XElement e = node as XElement;
         return ((((e != null) && (this.name == e.name)) && base.ContentsEqual(e)) && this.AttributesEqual(e));
      }

      public IEnumerable<XNode> DescendantNodesAndSelf()
      {
         return base.GetDescendantNodes(true);
      }

      public IEnumerable<XElement> DescendantsAndSelf()
      {
         return base.GetDescendants(null, true);
      }

      public IEnumerable<XElement> DescendantsAndSelf(XName name)
      {
         if (name == null)
         {
            return EmptySequence;
         }
         return base.GetDescendants(name, true);
      }

      internal override int GetDeepHashCode()
      {
         int num = this.name.GetHashCode() ^ base.ContentsHashCode();
         XAttribute lastAttr = this.lastAttr;
         if (lastAttr != null)
         {
            do
            {
               lastAttr = lastAttr.next;
               num ^= lastAttr.GetDeepHashCode();
            }
            while (lastAttr != this.lastAttr);
         }
         return num;
      }

      public XNamespace GetDefaultNamespace()
      {
         string namespaceOfPrefixInScope = this.GetNamespaceOfPrefixInScope("xmlns", null);
         if (namespaceOfPrefixInScope == null)
         {
            return XNamespace.None;
         }
         return XNamespace.Get(namespaceOfPrefixInScope);
      }

      public XNamespace GetNamespaceOfPrefix(string prefix)
      {
         if (prefix == null)
         {
            throw new ArgumentNullException("prefix");
         }
         if (prefix.Length == 0)
         {
            throw new ArgumentException(System.Xml.Linq.Res.GetString("Argument_InvalidPrefix", new object[] { prefix }));
         }
         if (prefix == "xmlns")
         {
            return XNamespace.Xmlns;
         }
         string namespaceOfPrefixInScope = this.GetNamespaceOfPrefixInScope(prefix, null);
         if (namespaceOfPrefixInScope != null)
         {
            return XNamespace.Get(namespaceOfPrefixInScope);
         }
         if (prefix == "xml")
         {
            return XNamespace.Xml;
         }
         return null;
      }

      private string GetNamespaceOfPrefixInScope(string prefix, XElement outOfScope)
      {
         for (XElement element = this; element != outOfScope; element = element.parent as XElement)
         {
            XAttribute lastAttr = element.lastAttr;
            if (lastAttr != null)
            {
               do
               {
                  lastAttr = lastAttr.next;
                  if (lastAttr.IsNamespaceDeclaration && (lastAttr.Name.LocalName == prefix))
                  {
                     return lastAttr.Value;
                  }
               }
               while (lastAttr != element.lastAttr);
            }
         }
         return null;
      }

      public string GetPrefixOfNamespace(XNamespace ns)
      {
         if (ns == null)
         {
            throw new ArgumentNullException("ns");
         }
         string namespaceName = ns.NamespaceName;
         bool flag = false;
         XElement outOfScope = this;
         do
         {
            XAttribute lastAttr = outOfScope.lastAttr;
            if (lastAttr != null)
            {
               bool flag2 = false;
               do
               {
                  lastAttr = lastAttr.next;
                  if (lastAttr.IsNamespaceDeclaration)
                  {
                     if (((lastAttr.Value == namespaceName) && (lastAttr.Name.NamespaceName.Length != 0)) && (!flag || (this.GetNamespaceOfPrefixInScope(lastAttr.Name.LocalName, outOfScope) == null)))
                     {
                        return lastAttr.Name.LocalName;
                     }
                     flag2 = true;
                  }
               }
               while (lastAttr != outOfScope.lastAttr);
               flag |= flag2;
            }
            outOfScope = outOfScope.parent as XElement;
         }
         while (outOfScope != null);
         switch (namespaceName)
         {
            case "http://www.w3.org/XML/1998/namespace":
            if (!flag || (this.GetNamespaceOfPrefixInScope("xml", null) == null))
            {
               return "xml";
            }
            break;

            case "http://www.w3.org/2000/xmlns/":
            return "xmlns";
         }
         return null;
      }

      public static XElement Load(TextReader textReader)
      {
         return Load(textReader, LoadOptions.None);
      }

      public static XElement Load(string uri)
      {
         return Load(uri, LoadOptions.None);
      }

      public static XElement Load(XmlReader reader)
      {
         return Load(reader, LoadOptions.None);
      }

      public static XElement Load(TextReader textReader, LoadOptions options)
      {
         XmlReaderSettings xmlReaderSettings = XNode.GetXmlReaderSettings(options);
         using (XmlReader reader = XmlReader.Create(textReader, xmlReaderSettings))
         {
            return Load(reader, options);
         }
      }

      public static XElement Load(string uri, LoadOptions options)
      {
         XmlReaderSettings xmlReaderSettings = XNode.GetXmlReaderSettings(options);
         using (XmlReader reader = XmlReader.Create(uri, xmlReaderSettings))
         {
            return Load(reader, options);
         }
      }

      public static XElement Load(XmlReader reader, LoadOptions options)
      {
         if (reader == null)
         {
            throw new ArgumentNullException("reader");
         }
         if (reader.MoveToContent() != XmlNodeType.Element)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExpectedNodeType", new object[] { XmlNodeType.Element, reader.NodeType }));
         }
         XElement element = new XElement(reader, options);
         reader.MoveToContent();
         if (!reader.EOF)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExpectedEndOfFile"));
         }
         return element;
      }

      [CLSCompliant(false)]
      public static explicit operator bool(XElement element)
      {
         if (element == null)
         {
            throw new ArgumentNullException("element");
         }
         return XmlConvert.ToBoolean(element.Value.ToLower(CultureInfo.InvariantCulture));
      }

      [CLSCompliant(false)]
      public static explicit operator DateTimeOffset(XElement element)
      {
         if (element == null)
         {
            throw new ArgumentNullException("element");
         }
         return XmlConvert.ToDateTimeOffset(element.Value);
      }

      [CLSCompliant(false)]
      public static explicit operator bool?(XElement element)
      {
         if (element == null)
         {
            return null;
         }
         return new bool?(XmlConvert.ToBoolean(element.Value.ToLower(CultureInfo.InvariantCulture)));
      }

      [CLSCompliant(false)]
      public static explicit operator long(XElement element)
      {
         if (element == null)
         {
            throw new ArgumentNullException("element");
         }
         return XmlConvert.ToInt64(element.Value);
      }

      [CLSCompliant(false)]
      public static explicit operator DateTime?(XElement element)
      {
         if (element == null)
         {
            return null;
         }
         return new DateTime?(DateTime.Parse(element.Value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind));
      }

      [CLSCompliant(false)]
      public static explicit operator Guid(XElement element)
      {
         if (element == null)
         {
            throw new ArgumentNullException("element");
         }
         return XmlConvert.ToGuid(element.Value);
      }

      [CLSCompliant(false)]
      public static explicit operator DateTimeOffset?(XElement element)
      {
         if (element == null)
         {
            return null;
         }
         return new DateTimeOffset?(XmlConvert.ToDateTimeOffset(element.Value));
      }

      [CLSCompliant(false)]
      public static explicit operator decimal?(XElement element)
      {
         if (element == null)
         {
            return null;
         }
         return new decimal?(XmlConvert.ToDecimal(element.Value));
      }

      [CLSCompliant(false)]
      public static explicit operator double?(XElement element)
      {
         if (element == null)
         {
            return null;
         }
         return new double?(XmlConvert.ToDouble(element.Value));
      }

      [CLSCompliant(false)]
      public static explicit operator Guid?(XElement element)
      {
         if (element == null)
         {
            return null;
         }
         return new Guid?(XmlConvert.ToGuid(element.Value));
      }

      [CLSCompliant(false)]
      public static explicit operator int(XElement element)
      {
         if (element == null)
         {
            throw new ArgumentNullException("element");
         }
         return XmlConvert.ToInt32(element.Value);
      }

      [CLSCompliant(false)]
      public static explicit operator int?(XElement element)
      {
         if (element == null)
         {
            return null;
         }
         return new int?(XmlConvert.ToInt32(element.Value));
      }

      [CLSCompliant(false)]
      public static explicit operator DateTime(XElement element)
      {
         if (element == null)
         {
            throw new ArgumentNullException("element");
         }
         return DateTime.Parse(element.Value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);
      }

      [CLSCompliant(false)]
      public static explicit operator long?(XElement element)
      {
         if (element == null)
         {
            return null;
         }
         return new long?(XmlConvert.ToInt64(element.Value));
      }

      [CLSCompliant(false)]
      public static explicit operator float?(XElement element)
      {
         if (element == null)
         {
            return null;
         }
         return new float?(XmlConvert.ToSingle(element.Value));
      }

      [CLSCompliant(false)]
      public static explicit operator TimeSpan?(XElement element)
      {
         if (element == null)
         {
            return null;
         }
         return new TimeSpan?(XmlConvert.ToTimeSpan(element.Value));
      }

      [CLSCompliant(false)]
      public static explicit operator decimal(XElement element)
      {
         if (element == null)
         {
            throw new ArgumentNullException("element");
         }
         return XmlConvert.ToDecimal(element.Value);
      }

      [CLSCompliant(false)]
      public static explicit operator uint?(XElement element)
      {
         if (element == null)
         {
            return null;
         }
         return new uint?(XmlConvert.ToUInt32(element.Value));
      }

      [CLSCompliant(false)]
      public static explicit operator ulong?(XElement element)
      {
         if (element == null)
         {
            return null;
         }
         return new ulong?(XmlConvert.ToUInt64(element.Value));
      }

      [CLSCompliant(false)]
      public static explicit operator double(XElement element)
      {
         if (element == null)
         {
            throw new ArgumentNullException("element");
         }
         return XmlConvert.ToDouble(element.Value);
      }

      [CLSCompliant(false)]
      public static explicit operator float(XElement element)
      {
         if (element == null)
         {
            throw new ArgumentNullException("element");
         }
         return XmlConvert.ToSingle(element.Value);
      }

      [CLSCompliant(false)]
      public static explicit operator string(XElement element)
      {
         if (element == null)
         {
            return null;
         }
         return element.Value;
      }

      [CLSCompliant(false)]
      public static explicit operator TimeSpan(XElement element)
      {
         if (element == null)
         {
            throw new ArgumentNullException("element");
         }
         return XmlConvert.ToTimeSpan(element.Value);
      }

      [CLSCompliant(false)]
      public static explicit operator uint(XElement element)
      {
         if (element == null)
         {
            throw new ArgumentNullException("element");
         }
         return XmlConvert.ToUInt32(element.Value);
      }

      [CLSCompliant(false)]
      public static explicit operator ulong(XElement element)
      {
         if (element == null)
         {
            throw new ArgumentNullException("element");
         }
         return XmlConvert.ToUInt64(element.Value);
      }

      public static XElement Parse(string text)
      {
         return Parse(text, LoadOptions.None);
      }

      public static XElement Parse(string text, LoadOptions options)
      {
         XElement element;
         using (StringReader reader = new StringReader(text))
         {
            XmlReaderSettings xmlReaderSettings = XNode.GetXmlReaderSettings(options);
            using (XmlReader reader2 = XmlReader.Create(reader, xmlReaderSettings))
            {
               element = Load(reader2, options);
            }
         }
         return element;
      }

      private void ReadElementFrom(XmlReader r, LoadOptions o)
      {
         if (r.ReadState != ReadState.Interactive)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExpectedInteractive"));
         }
         this.name = XNamespace.Get(r.NamespaceURI).GetName(r.LocalName);
         if ((o & LoadOptions.SetBaseUri) != LoadOptions.None)
         {
            string baseURI = r.BaseURI;
            if ((baseURI != null) && (baseURI.Length != 0))
            {
               base.SetBaseUri(baseURI);
            }
         }
         IXmlLineInfo info = null;
         if ((o & LoadOptions.SetLineInfo) != LoadOptions.None)
         {
            info = r as IXmlLineInfo;
            if ((info != null) && info.HasLineInfo())
            {
               base.SetLineInfo(info.LineNumber, info.LinePosition);
            }
         }
         if (r.MoveToFirstAttribute())
         {
            do
            {
               XAttribute a = new XAttribute(XNamespace.Get((r.Prefix.Length == 0) ? string.Empty : r.NamespaceURI).GetName(r.LocalName), r.Value);
               if ((info != null) && info.HasLineInfo())
               {
                  a.SetLineInfo(info.LineNumber, info.LinePosition);
               }
               this.AppendAttributeSkipNotify(a);
            }
            while (r.MoveToNextAttribute());
            r.MoveToElement();
         }
         if (!r.IsEmptyElement)
         {
            r.Read();
            base.ReadContentFrom(r, o);
         }
         r.Read();
      }

      public void RemoveAll()
      {
         this.RemoveAttributes();
         base.RemoveNodes();
      }

      internal void RemoveAttribute(XAttribute a)
      {
         XAttribute attribute2;
         bool flag = base.NotifyChanging(a, XObjectChangeEventArgs.Remove);
         if (a.parent != this)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExternalCode"));
         }
         XAttribute lastAttr = this.lastAttr;
         while ((attribute2 = lastAttr.next) != a)
         {
            lastAttr = attribute2;
         }
         if (lastAttr == a)
         {
            this.lastAttr = null;
         }
         else
         {
            if (this.lastAttr == a)
            {
               this.lastAttr = lastAttr;
            }
            lastAttr.next = a.next;
         }
         a.parent = null;
         a.next = null;
         if (flag)
         {
            base.NotifyChanged(a, XObjectChangeEventArgs.Remove);
         }
      }

      public void RemoveAttributes()
      {
         if (base.SkipNotify())
         {
            this.RemoveAttributesSkipNotify();
         }
         else
         {
            while (this.lastAttr != null)
            {
               XAttribute next = this.lastAttr.next;
               base.NotifyChanging(next, XObjectChangeEventArgs.Remove);
               if ((this.lastAttr == null) || (next != this.lastAttr.next))
               {
                  throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExternalCode"));
               }
               if (next != this.lastAttr)
               {
                  this.lastAttr.next = next.next;
               }
               else
               {
                  this.lastAttr = null;
               }
               next.parent = null;
               next.next = null;
               base.NotifyChanged(next, XObjectChangeEventArgs.Remove);
            }
         }
      }

      private void RemoveAttributesSkipNotify()
      {
         if (this.lastAttr != null)
         {
            XAttribute lastAttr = this.lastAttr;
            do
            {
               XAttribute next = lastAttr.next;
               lastAttr.parent = null;
               lastAttr.next = null;
               lastAttr = next;
            }
            while (lastAttr != this.lastAttr);
            this.lastAttr = null;
         }
      }

      public void ReplaceAll(object content)
      {
         content = XContainer.GetContentSnapshot(content);
         this.RemoveAll();
         base.Add(content);
      }

      public void ReplaceAll(params object[] content)
      {
         this.ReplaceAll(content);
      }

      public void ReplaceAttributes(object content)
      {
         content = XContainer.GetContentSnapshot(content);
         this.RemoveAttributes();
         base.Add(content);
      }

      public void ReplaceAttributes(params object[] content)
      {
         this.ReplaceAttributes(content);
      }

      public void Save(TextWriter textWriter)
      {
         this.Save(textWriter, SaveOptions.None);
      }

      public void Save(string fileName)
      {
         this.Save(fileName, SaveOptions.None);
      }

      public void Save(XmlWriter writer)
      {
         if (writer == null)
         {
            throw new ArgumentNullException("writer");
         }
         writer.WriteStartDocument();
         this.WriteTo(writer);
         writer.WriteEndDocument();
      }

      public void Save(TextWriter textWriter, SaveOptions options)
      {
         XmlWriterSettings xmlWriterSettings = XNode.GetXmlWriterSettings(options);
         using (XmlWriter writer = XmlWriter.Create(textWriter, xmlWriterSettings))
         {
            this.Save(writer);
         }
      }

      public void Save(string fileName, SaveOptions options)
      {
         XmlWriterSettings xmlWriterSettings = XNode.GetXmlWriterSettings(options);
         using (XmlWriter writer = XmlWriter.Create(fileName, xmlWriterSettings))
         {
            this.Save(writer);
         }
      }

      public void SetAttributeValue(XName name, object value)
      {
         XAttribute a = this.Attribute(name);
         if (value == null)
         {
            if (a != null)
            {
               this.RemoveAttribute(a);
            }
         }
         else if (a != null)
         {
            a.Value = XContainer.GetStringValue(value);
         }
         else
         {
            this.AppendAttribute(new XAttribute(name, value));
         }
      }

      public void SetElementValue(XName name, object value)
      {
         XElement n = base.Element(name);
         if (value == null)
         {
            if (n != null)
            {
               base.RemoveNode(n);
            }
         }
         else if (n != null)
         {
            n.Value = XContainer.GetStringValue(value);
         }
         else
         {
            base.AddNode(new XElement(name, XContainer.GetStringValue(value)));
         }
      }

      public void SetValue(object value)
      {
         if (value == null)
         {
            throw new ArgumentNullException("value");
         }
         this.Value = XContainer.GetStringValue(value);
      }

      XmlSchema IXmlSerializable.GetSchema()
      {
         return null;
      }

      void IXmlSerializable.ReadXml(XmlReader reader)
      {
         if (reader == null)
         {
            throw new ArgumentNullException("reader");
         }
         if (((base.parent != null) || (base.annotations != null)) || ((base.content != null) || (this.lastAttr != null)))
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_DeserializeInstance"));
         }
         if (reader.MoveToContent() != XmlNodeType.Element)
         {
            throw new InvalidOperationException(System.Xml.Linq.Res.GetString("InvalidOperation_ExpectedNodeType", new object[] { XmlNodeType.Element, reader.NodeType }));
         }
         this.ReadElementFrom(reader, LoadOptions.None);
      }

      void IXmlSerializable.WriteXml(XmlWriter writer)
      {
         this.WriteTo(writer);
      }

      internal override void ValidateNode(XNode node, XNode previous)
      {
         if (node is XDocument)
         {
            throw new ArgumentException(System.Xml.Linq.Res.GetString("Argument_AddNode", new object[] { XmlNodeType.Document }));
         }
         if (node is XDocumentType)
         {
            throw new ArgumentException(System.Xml.Linq.Res.GetString("Argument_AddNode", new object[] { XmlNodeType.DocumentType }));
         }
      }

      public override void WriteTo(XmlWriter writer)
      {
         if (writer == null)
         {
            throw new ArgumentNullException("writer");
         }
         new ElementWriter(writer).WriteElement(this);
      }

      public static IEnumerable<XElement> EmptySequence
      {
         get
         {
            if (emptySequence == null)
            {
               emptySequence = new XElement[0];
            }
            return emptySequence;
         }
      }

      public XAttribute FirstAttribute
      {
         get
         {
            if (this.lastAttr == null)
            {
               return null;
            }
            return this.lastAttr.next;
         }
      }

      public bool HasAttributes
      {
         get
         {
            return (this.lastAttr != null);
         }
      }

      public bool HasElements
      {
         get
         {
            XNode content = base.content as XNode;
            if (content != null)
            {
               do
               {
                  if (content is XElement)
                  {
                     return true;
                  }
                  content = content.next;
               }
               while (content != base.content);
            }
            return false;
         }
      }

      public bool IsEmpty
      {
         get
         {
            return (base.content == null);
         }
      }

      public XAttribute LastAttribute
      {
         get
         {
            return this.lastAttr;
         }
      }

      public XName Name
      {
         get
         {
            return this.name;
         }
         set
         {
            if (value == null)
            {
               throw new ArgumentNullException("value");
            }
            bool flag = base.NotifyChanging(this, XObjectChangeEventArgs.Name);
            this.name = value;
            if (flag)
            {
               base.NotifyChanged(this, XObjectChangeEventArgs.Name);
            }
         }
      }

      public override XmlNodeType NodeType
      {
         get
         {
            return XmlNodeType.Element;
         }
      }

      public string Value
      {
         get
         {
            if (base.content == null)
            {
               return string.Empty;
            }
            string content = base.content as string;
            if (content != null)
            {
               return content;
            }
            StringBuilder sb = new StringBuilder();
            this.AppendText(sb);
            return sb.ToString();
         }
         set
         {
            if (value == null)
            {
               throw new ArgumentNullException("value");
            }
            base.RemoveNodes();
            base.Add(value);
         }
      }
   }

   public class XAttribute : XObject
   {
      // Fields
      private static IEnumerable<XAttribute> emptySequence;
      internal XName name;
      internal XAttribute next;
      internal string value;

      // Methods
      public XAttribute(XAttribute other)
      {
         if (other == null)
         {
            throw new ArgumentNullException("other");
         }
         this.name = other.name;
         this.value = other.value;
      }

      public XAttribute(XName name, object value)
      {
         if (name == null)
         {
            throw new ArgumentNullException("name");
         }
         if (value == null)
         {
            throw new ArgumentNullException("value");
         }
         string stringValue = XContainer.GetStringValue(value);
         ValidateAttribute(name, stringValue);
         this.name = name;
         this.value = stringValue;
      }

      internal int GetDeepHashCode()
      {
         return (this.name.GetHashCode() ^ this.value.GetHashCode());
      }

      [CLSCompliant(false)]
      public static explicit operator DateTime?(XAttribute attribute)
      {
         if (attribute == null)
         {
            return null;
         }
         return new DateTime?(DateTime.Parse(attribute.value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind));
      }

      [CLSCompliant(false)]
      public static explicit operator bool(XAttribute attribute)
      {
         if (attribute == null)
         {
            throw new ArgumentNullException("attribute");
         }
         return XmlConvert.ToBoolean(attribute.value.ToLower(CultureInfo.InvariantCulture));
      }

      [CLSCompliant(false)]
      public static explicit operator Guid(XAttribute attribute)
      {
         if (attribute == null)
         {
            throw new ArgumentNullException("attribute");
         }
         return XmlConvert.ToGuid(attribute.value);
      }

      [CLSCompliant(false)]
      public static explicit operator bool?(XAttribute attribute)
      {
         if (attribute == null)
         {
            return null;
         }
         return new bool?(XmlConvert.ToBoolean(attribute.value.ToLower(CultureInfo.InvariantCulture)));
      }

      [CLSCompliant(false)]
      public static explicit operator int(XAttribute attribute)
      {
         if (attribute == null)
         {
            throw new ArgumentNullException("attribute");
         }
         return XmlConvert.ToInt32(attribute.value);
      }

      [CLSCompliant(false)]
      public static explicit operator Guid?(XAttribute attribute)
      {
         if (attribute == null)
         {
            return null;
         }
         return new Guid?(XmlConvert.ToGuid(attribute.value));
      }

      [CLSCompliant(false)]
      public static explicit operator int?(XAttribute attribute)
      {
         if (attribute == null)
         {
            return null;
         }
         return new int?(XmlConvert.ToInt32(attribute.value));
      }

      [CLSCompliant(false)]
      public static explicit operator TimeSpan?(XAttribute attribute)
      {
         if (attribute == null)
         {
            return null;
         }
         return new TimeSpan?(XmlConvert.ToTimeSpan(attribute.value));
      }

      [CLSCompliant(false)]
      public static explicit operator DateTime(XAttribute attribute)
      {
         if (attribute == null)
         {
            throw new ArgumentNullException("attribute");
         }
         return DateTime.Parse(attribute.value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);
      }

      [CLSCompliant(false)]
      public static explicit operator DateTimeOffset?(XAttribute attribute)
      {
         if (attribute == null)
         {
            return null;
         }
         return new DateTimeOffset?(XmlConvert.ToDateTimeOffset(attribute.value));
      }

      [CLSCompliant(false)]
      public static explicit operator long?(XAttribute attribute)
      {
         if (attribute == null)
         {
            return null;
         }
         return new long?(XmlConvert.ToInt64(attribute.value));
      }

      [CLSCompliant(false)]
      public static explicit operator ulong?(XAttribute attribute)
      {
         if (attribute == null)
         {
            return null;
         }
         return new ulong?(XmlConvert.ToUInt64(attribute.value));
      }

      [CLSCompliant(false)]
      public static explicit operator DateTimeOffset(XAttribute attribute)
      {
         if (attribute == null)
         {
            throw new ArgumentNullException("attribute");
         }
         return XmlConvert.ToDateTimeOffset(attribute.value);
      }

      [CLSCompliant(false)]
      public static explicit operator float?(XAttribute attribute)
      {
         if (attribute == null)
         {
            return null;
         }
         return new float?(XmlConvert.ToSingle(attribute.value));
      }

      [CLSCompliant(false)]
      public static explicit operator decimal(XAttribute attribute)
      {
         if (attribute == null)
         {
            throw new ArgumentNullException("attribute");
         }
         return XmlConvert.ToDecimal(attribute.value);
      }

      [CLSCompliant(false)]
      public static explicit operator double?(XAttribute attribute)
      {
         if (attribute == null)
         {
            return null;
         }
         return new double?(XmlConvert.ToDouble(attribute.value));
      }

      [CLSCompliant(false)]
      public static explicit operator double(XAttribute attribute)
      {
         if (attribute == null)
         {
            throw new ArgumentNullException("attribute");
         }
         return XmlConvert.ToDouble(attribute.value);
      }

      [CLSCompliant(false)]
      public static explicit operator decimal?(XAttribute attribute)
      {
         if (attribute == null)
         {
            return null;
         }
         return new decimal?(XmlConvert.ToDecimal(attribute.value));
      }

      [CLSCompliant(false)]
      public static explicit operator long(XAttribute attribute)
      {
         if (attribute == null)
         {
            throw new ArgumentNullException("attribute");
         }
         return XmlConvert.ToInt64(attribute.value);
      }

      [CLSCompliant(false)]
      public static explicit operator uint?(XAttribute attribute)
      {
         if (attribute == null)
         {
            return null;
         }
         return new uint?(XmlConvert.ToUInt32(attribute.value));
      }

      [CLSCompliant(false)]
      public static explicit operator float(XAttribute attribute)
      {
         if (attribute == null)
         {
            throw new ArgumentNullException("attribute");
         }
         return XmlConvert.ToSingle(attribute.value);
      }

      [CLSCompliant(false)]
      public static explicit operator string(XAttribute attribute)
      {
         if (attribute == null)
         {
            return null;
         }
         return attribute.value;
      }

      [CLSCompliant(false)]
      public static explicit operator TimeSpan(XAttribute attribute)
      {
         if (attribute == null)
         {
            throw new ArgumentNullException("attribute");
         }
         return XmlConvert.ToTimeSpan(attribute.value);
      }

      [CLSCompliant(false)]
      public static explicit operator uint(XAttribute attribute)
      {
         if (attribute == null)
         {
            throw new ArgumentNullException("attribute");
         }
         return XmlConvert.ToUInt32(attribute.value);
      }

      [CLSCompliant(false)]
      public static explicit operator ulong(XAttribute attribute)
      {
         if (attribute == null)
         {
            throw new ArgumentNullException("attribute");
         }
         return XmlConvert.ToUInt64(attribute.value);
      }

      public void Remove()
      {
         if (base.parent == null)
         {
            throw new InvalidOperationException("InvalidOperation: MissingParent");
         }
         ((XElement)base.parent).RemoveAttribute(this);
      }

      public void SetValue(object value)
      {
         if (value == null)
         {
            throw new ArgumentNullException("value");
         }
         this.Value = XContainer.GetStringValue(value);
      }

      public override string ToString()
      {
         using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture))
         {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.ConformanceLevel = ConformanceLevel.Fragment;
            using (XmlWriter writer2 = XmlWriter.Create(writer, settings))
            {
               writer2.WriteAttributeString(this.GetPrefixOfNamespace(this.name.Namespace), this.name.LocalName, this.name.NamespaceName, this.value);
            }
            return writer.ToString().Trim();
         }
      }

      private static void ValidateAttribute(XName name, string value)
      {
         string namespaceName = name.NamespaceName;
         if (namespaceName == "http://www.w3.org/2000/xmlns/")
         {
            if (value.Length == 0)
            {
               throw new ArgumentException(Res.GetString("Argument_NamespaceDeclarationPrefixed", new object[] { name.LocalName }));
            }
            if (value != "http://www.w3.org/XML/1998/namespace")
            {
               if (value == "http://www.w3.org/2000/xmlns/")
               {
                  throw new ArgumentException(Res.GetString("Argument_NamespaceDeclarationXmlns"));
               }
               switch (name.LocalName)
               {
                  case "xml":
                  throw new ArgumentException(Res.GetString("Argument_NamespaceDeclarationXml"));

                  case "xmlns":
                  throw new ArgumentException(Res.GetString("Argument_NamespaceDeclarationXmlns"));
               }
            }
            else if (name.LocalName != "xml")
            {
               throw new ArgumentException(Res.GetString("Argument_NamespaceDeclarationXml"));
            }
         }
         else if ((namespaceName.Length == 0) && (name.LocalName == "xmlns"))
         {
            if (value == "http://www.w3.org/XML/1998/namespace")
            {
               throw new ArgumentException(Res.GetString("Argument_NamespaceDeclarationXml"));
            }
            if (value == "http://www.w3.org/2000/xmlns/")
            {
               throw new ArgumentException(Res.GetString("Argument_NamespaceDeclarationXmlns"));
            }
         }
      }

      // Properties
      public static IEnumerable<XAttribute> EmptySequence
      {
         get
         {
            if (emptySequence == null)
            {
               emptySequence = new XAttribute[0];
            }
            return emptySequence;
         }
      }

      public bool IsNamespaceDeclaration
      {
         get
         {
            string namespaceName = this.name.NamespaceName;
            if (namespaceName.Length == 0)
            {
               return (this.name.LocalName == "xmlns");
            }
            return (namespaceName == "http://www.w3.org/2000/xmlns/");
         }
      }

      public XName Name
      {
         get
         {
            return this.name;
         }
      }

      public XAttribute NextAttribute
      {
         get
         {
            if ((base.parent != null) && (((XElement)base.parent).lastAttr != this))
            {
               return this.next;
            }
            return null;
         }
      }

      public override XmlNodeType NodeType
      {
         get
         {
            return XmlNodeType.Attribute;
         }
      }

      public XAttribute PreviousAttribute
      {
         get
         {
            if (base.parent == null)
            {
               return null;
            }
            XAttribute lastAttr = ((XElement)base.parent).lastAttr;
            while (lastAttr.next != this)
            {
               lastAttr = lastAttr.next;
            }
            if (lastAttr == ((XElement)base.parent).lastAttr)
            {
               return null;
            }
            return lastAttr;
         }
      }

      public string Value
      {
         get
         {
            return this.value;
         }
         set
         {
            if (value == null)
            {
               throw new ArgumentNullException("value");
            }
            ValidateAttribute(this.name, value);
            bool flag = base.NotifyChanging(this, XObjectChangeEventArgs.Value);
            this.value = value;
            if (flag)
            {
               base.NotifyChanged(this, XObjectChangeEventArgs.Value);
            }
         }
      }
   }
}
